<!-- EditableContent.vue -->
<template>
  <div class="editable-container">
    <div
      ref="editor"
      :class="['editable-area', { 'has-placeholder': showPlaceholder }]"
      @input="handleInput"
      @keydown="handleKeydown"
      @compositionstart="handleCompositionStart"
      @paste="handlePaste"
      @blur="emitBlur"
      :style="customStyles"
      :contenteditable="editable"
    ></div>
  </div>
</template>

<script setup lang="ts">
  import { EditOutlined, CheckOutlined } from '@ant-design/icons-vue';

  import {
    ref,
    watch,
    nextTick,
    onMounted,
    defineProps,
    defineEmits,
    withDefaults,
  } from 'vue';

  interface Props {
    modelValue: string;
    maxLength?: number;
    placeholder?: string;
    disabled?: boolean;
    customStyles?: Record<string, string>;
    editable?: boolean;
  }

  const props = withDefaults(defineProps<Props>(), {
    maxLength: Infinity,
    placeholder: '请输入内容...',
    disabled: false,
    editable: false,
    customStyles: () => ({}),
  });

  const emit = defineEmits(['update:modelValue', 'input', 'blur']);

  const editor = ref<HTMLElement | null>(null);
  const isComposing = ref(false);
  const showPlaceholder = ref(false);
  let lastSelection: Range | null = null;

  // 初始化内容
  onMounted(() => {
    if (editor.value) {
      editor.value.textContent = props.modelValue;
      updatePlaceholderState();
    }
  });

  // 输入处理
  const handleInput = (e: Event) => {
    if (isComposing.value || !editor.value) return;

    const newContent = editor.value.textContent || '';
    if (newContent.length > props.maxLength) {
      editor.value.textContent = newContent.slice(0, props.maxLength);
      restoreCursor();
    }

    emit('update:modelValue', newContent);
    emit('input', newContent);
    updatePlaceholderState();
    saveSelection();
    scrollToBottom();
  };
  const emitBlur = () => {
    emit('blur', '');
  };

  // 删除键处理（优化光标行为）
  const handleKeydown = (e: KeyboardEvent) => {
    if (['Backspace', 'Delete'].includes(e.key)) {
      e.preventDefault();
      document.execCommand('delete', false, undefined);
      saveSelection();
    }
  };

  // 输入法状态处理
  const handleCompositionStart = () => {
    isComposing.value = true;
    document.addEventListener('compositionend', handleCompositionEnd);
  };

  const handleCompositionEnd = () => {
    isComposing.value = false;
    document.removeEventListener('compositionend', handleCompositionEnd);
  };

  // 安全粘贴处理（参考网页5安全实践）
  const handlePaste = (e: ClipboardEvent) => {
    e.preventDefault();
    const text = e.clipboardData?.getData('text/plain') || '';
    document.execCommand('insertText', false, text);
    saveSelection();
  };

  // 光标管理（结合网页6、7的最佳实践）
  const saveSelection = () => {
    const sel = window.getSelection();
    if (sel && sel.rangeCount > 0) {
      lastSelection = sel.getRangeAt(0).cloneRange();
    }
  };

  const restoreCursor = () => {
    nextTick(() => {
      if (!lastSelection || !editor.value) return;

      const sel = window.getSelection();
      sel?.removeAllRanges();
      sel?.addRange(lastSelection.cloneRange());
    });
  };

  const scrollToBottom = () => {
    nextTick(() => {
      if (!editor.value) return;
      // 使用requestAnimationFrame优化滚动性能[4](@ref)
      editor.value!.scrollTop = editor.value!.scrollHeight;
    });
  };

  // 双向绑定同步
  watch(
    () => props.modelValue,
    (newVal) => {
      if (editor.value?.textContent !== newVal) {
        editor.value!.textContent = newVal;
        updatePlaceholderState();
        scrollToBottom(); //
      }
    },
  );

  watch(
    () => props.editable,
    (newVal) => {
      if (newVal && editor.value) {
       
      }
    },
  );

  // 占位符状态管理
  const updatePlaceholderState = () => {
    showPlaceholder.value = !editor.value?.textContent?.trim();
  };

  // 暴露组件方法
  defineExpose({
    scrollToBottom,
    focus: () => editor.value?.focus(),
    clear: () => {
      if (editor.value) {
        editor.value.textContent = '';
        emit('update:modelValue', '');
      }
    },
  });
</script>

<style scoped>
  .editable-area {
    height: 100%;
    outline: none;
    transition: border-color 0.2s;
    flex: none;
    overflow-y: auto;
    padding: 5px;

    background-color: #fff;

    word-break: break-all; /* 允许在任意字符间断行 */
    white-space: pre-wrap; /* 保留空白符和换行 */
    overflow-wrap: break-word; /* 防止长单词溢出 */

    &:focus {
      border-color: #409eff;
    }

    &.has-placeholder::before {
      content: attr(data-placeholder);
      color: #c0c4cc;
      position: absolute;
    }

    &[contenteditable='false'] {
      background-color: #f5f7fa00;
      /* background-color: #f5f7fa; */
      /* cursor: not-allowed; */
      cursor: default;
    }
  }

  .editable-area::-webkit-scrollbar {
    width: 0 !important; /* 垂直滚动条 */
    height: 0 !important; /* 水平滚动条 */
  }

  .editable-container {
    /* position: relative; */
    /* display: flex;
    align-items: center; */
  }
</style>
